package com.rui.prototype.model;

import lombok.Data;

import java.io.*;

/**
 * 深克隆
 */
@Data
public class DeepClazz implements Cloneable, Serializable {

    // DeepClazz类
    private static DeepClazz clazz = new DeepClazz();

    private String name;
    private Student student;

    private DeepClazz() {
    }

    public static DeepClazz getInstance() {
        return clazz;
    }

    public static void main(String[] args) throws Exception {
        DeepClazz clazz1 = DeepClazz.getInstance();
        clazz1.setName("高三一班");
        Student stu1 = new Student("张三", "男", 18);
        clazz1.setStudent(stu1);

        DeepClazz clazz3 = (DeepClazz) clazz1.deepClone();
        Student stu3 = clazz3.getStudent();
        stu3.setName("王五");
        // Clazz(name=高三一班, student=Student(name=张三, sex=男, age=18))
        System.out.println(clazz1);
        // Clazz(name=高三一班, student=Student(name=王五, sex=男, age=18))
        System.out.println(clazz3);
    }

    @Override
    public Object clone() throws CloneNotSupportedException {

        // 看到clazz1和clazz2并不相等，也就是说他们并不是同一个对象，也就是单例被破坏了。
        // return super.clone();

        // 解决办法也很简单，首先第一个就是不实现Cloneable接口即可，但是不实现Cloneable接口进行clone则会抛出CloneNotSupportedException异常。
        // 第二个方法就是重写clone()方法
        return clazz;
    }

    protected Object deepClone() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
}